package com.qf.aop;


import com.qf.entity.EndUser;
import com.qf.entity.User;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import com.qf.annotation.ProccessInfo;
import com.qf.entity.ProcessLog;
import com.qf.mapper.ProcessInfoMapper;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Date;


// https://blog.csdn.net/gottawangzi/article/details/82818330
@Component
@Aspect
public class ProcessAdvisor {

    private ProcessInfoMapper processInfoMapper;

    public ProcessAdvisor(ProcessInfoMapper processInfoMapper) {

        this.processInfoMapper = processInfoMapper;
    }

    /**
     * 只要方法头顶上加了该注解，那么在进入该方法之前都会调用该通知
     * @param jp
     */
    @Before("@annotation(com.qf.annotation.ProccessInfo)")
    public void processBefore(JoinPoint jp) {
        // 获取方法的签名
        MethodSignature methodSignature = (MethodSignature)jp.getSignature();

        Method method = methodSignature.getMethod();

        // 获取注解
        ProccessInfo proccessInfo = method.getAnnotation(ProccessInfo.class);

        ProcessLog pl = new ProcessLog();



        String info = proccessInfo.value(); //操作信息
        pl.setInfo(info);

        // 是否获取方法的参数
        boolean isGetParams = proccessInfo.requireParamInfo();
        String name = null;
        if(isGetParams) {  //表示需要获取请求的参数

            ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
            HttpSession session = attr.getRequest().getSession(true);
            EndUser user = (EndUser) session.getAttribute("endUser");
            name = user.getEndName();

            Parameter[] ps = method.getParameters(); // [a, b]  //获取所有的请求的参数  add(int a, int b) add(3, 4);
            Object[] objs = jp.getArgs(); //方法的调用的具体的值 // [3, 4]

            StringBuffer details = new StringBuffer();

            for(int i = 0; i < ps.length; i++) {
                String paramName = ps[i].getName(); // 获取请求参数的名字
                Object paramValue = objs[i]; //方法的请求值
                details.append(paramName + "=" + paramValue + ";");
            }

            pl.setDetail(details.toString());
        }

        pl.setCreateTime(new Date());
        pl.setUserId(1);
        pl.setName(name);

        processInfoMapper.insert(pl);
    }
}
